package com.seanzx.common;

import java.util.function.Function;

public class Result<T> {
    private final ResultCode resultCode;
    private T data;
    private Function<T, String> serialize = Object::toString;

    private Result(ResultCode resultCode) {
        this.resultCode = resultCode;
    }

    private Result(ResultCode resultCode, T data) {
        this.resultCode = resultCode;
        this.data = data;
    }

    public static Result<?> ok() {
        return new Result<>(ResultCode.SUCCESS);
    }

    public static<T> Result<T> ok(T data) {
        return new Result<>(ResultCode.SUCCESS, data);
    }

    public static Result<?> of(ResultCode errorCode) {
        return new Result<>(errorCode);
    }

    public static<T> Result<T> of(ResultCode errorCode, T data) {
        return new Result<>(errorCode, data);
    }

    public void serializeBy(Function<T, String> serialize) {
        this.serialize = serialize;
    }

    public ResultCode getResultCode() {
        return resultCode;
    }

    public T getData() {
        return data;
    }

    public String string() {
        if (isSuccess()) {
            if (data == null) {
                return resultCode.getMessage();
            }
            return resultCode.getMessage() + "\n" + serialize.apply(data);
        }
        return "exception[" + resultCode.getCode() + "]:" + resultCode.getMessage();
    }

    public boolean isSuccess() {
        return ResultCode.SUCCESS.getCode().equals(resultCode.getCode());
    }
}
